From 7b49ebe0ca2c394badcade8e4689b23b20a30648 Mon Sep 17 00:00:00 2001 From: Yehuda Katz + Carl Lerche Date: Tue, 8 Jul 2014 15:50:50 -0700 Subject: [PATCH] emit -C extra-filename and metadata --- src/cargo/core/manifest.rs | 46 ++++++++++++++++++++++++------------ src/cargo/core/package_id.rs | 18 ++++++++++++-- src/cargo/core/source.rs | 6 ++--- src/cargo/ops/cargo_rustc.rs | 23 +++++++++++++++--- src/cargo/util/hex.rs | 6 +++++ src/cargo/util/mod.rs | 2 +- src/cargo/util/toml.rs | 22 ++++++++++------- 7 files changed, 91 insertions(+), 32 deletions(-) diff --git a/src/cargo/core/manifest.rs b/src/cargo/core/manifest.rs index 048ef6ada..3eee27591 100644 --- a/src/cargo/core/manifest.rs +++ b/src/cargo/core/manifest.rs @@ -9,6 +9,7 @@ use core::{ PackageId, Summary }; +use core::package_id::Metadata; use core::dependency::SerializedDependency; use util::{CargoResult, human}; @@ -99,13 +100,13 @@ pub enum TargetKind { BinTarget } -#[deriving(Clone, Hash, PartialEq)] +#[deriving(Encodable, Decodable, Clone, Hash, PartialEq)] pub struct Profile { env: String, // compile, test, dev, bench, etc. opt_level: uint, debug: bool, test: bool, - dest: Option + dest: Option, } impl Profile { @@ -193,15 +194,18 @@ impl Profile { pub struct Target { kind: TargetKind, name: String, - path: Path, - profile: Profile + src_path: Path, + profile: Profile, + metadata: Option } #[deriving(Encodable)] pub struct SerializedTarget { kind: Vec<&'static str>, name: String, - path: String + src_path: String, + profile: Profile, + metadata: Option } impl> Encodable for Target { @@ -214,7 +218,9 @@ impl> Encodable for Target { SerializedTarget { kind: kind, name: self.name.clone(), - path: self.path.display().to_str() + src_path: self.src_path.display().to_str(), + profile: self.profile.clone(), + metadata: self.metadata.clone() }.encode(s) } } @@ -222,10 +228,11 @@ impl> Encodable for Target { impl Show for Target { fn fmt(&self, f: &mut Formatter) -> fmt::Result { write!(f, "{}(name={}, path={})", self.kind, self.name, - self.path.display()) + self.src_path.display()) } } + impl Manifest { pub fn new(summary: &Summary, targets: &[Target], target_dir: &Path, sources: Vec, @@ -292,21 +299,26 @@ impl Manifest { impl Target { pub fn lib_target(name: &str, crate_targets: Vec, - path: &Path, profile: &Profile) -> Target { + src_path: &Path, profile: &Profile, + metadata: &Metadata) + -> Target + { Target { kind: LibTarget(crate_targets), name: name.to_str(), - path: path.clone(), - profile: profile.clone() + src_path: src_path.clone(), + profile: profile.clone(), + metadata: Some(metadata.clone()) } } - pub fn bin_target(name: &str, path: &Path, profile: &Profile) -> Target { + pub fn bin_target(name: &str, src_path: &Path, profile: &Profile) -> Target { Target { kind: BinTarget, name: name.to_str(), - path: path.clone(), - profile: profile.clone() + src_path: src_path.clone(), + profile: profile.clone(), + metadata: None } } @@ -314,8 +326,8 @@ impl Target { self.name.as_slice() } - pub fn get_path<'a>(&'a self) -> &'a Path { - &self.path + pub fn get_src_path<'a>(&'a self) -> &'a Path { + &self.src_path } pub fn is_lib(&self) -> bool { @@ -336,6 +348,10 @@ impl Target { &self.profile } + pub fn get_metadata<'a>(&'a self) -> Option<&'a Metadata> { + self.metadata.as_ref() + } + pub fn rustc_crate_types(&self) -> Vec<&'static str> { match self.kind { LibTarget(ref kinds) => { diff --git a/src/cargo/core/package_id.rs b/src/cargo/core/package_id.rs index 61dfec353..03236aa36 100644 --- a/src/cargo/core/package_id.rs +++ b/src/cargo/core/package_id.rs @@ -9,7 +9,7 @@ use serialize::{ Decoder }; -use util::{CargoResult, CargoError}; +use util::{CargoResult, CargoError, short_hash}; use core::source::SourceId; trait ToVersion { @@ -53,7 +53,7 @@ impl<'a> ToUrl for &'a Url { } } -#[deriving(Clone,PartialEq)] +#[deriving(Clone, PartialEq)] pub struct PackageId { name: String, version: semver::Version, @@ -76,6 +76,12 @@ impl CargoError for PackageIdError { fn is_human(&self) -> bool { true } } +#[deriving(PartialEq, Hash, Clone, Encodable)] +pub struct Metadata { + pub metadata: String, + pub extra_filename: String +} + impl PackageId { pub fn new(name: &str, version: T, sid: &SourceId) -> CargoResult { @@ -98,6 +104,14 @@ impl PackageId { pub fn get_source_id<'a>(&'a self) -> &'a SourceId { &self.source_id } + + pub fn generate_metadata(&self) -> Metadata { + let metadata = format!("{}:-:{}:-:{}", self.name, self.version, self.source_id); + let extra_filename = short_hash( + &(self.name.as_slice(), self.version.to_str(), &self.source_id)); + + Metadata { metadata: metadata, extra_filename: extra_filename } + } } static central_repo: &'static str = "http://rust-lang.org/central-repo"; diff --git a/src/cargo/core/source.rs b/src/cargo/core/source.rs index 1046537af..22590a892 100644 --- a/src/cargo/core/source.rs +++ b/src/cargo/core/source.rs @@ -46,7 +46,7 @@ pub trait Source { fn fingerprint(&self, pkg: &Package) -> CargoResult; } -#[deriving(Encodable, Decodable, Show, Clone, PartialEq, Eq, PartialOrd, Ord)] +#[deriving(Encodable, Decodable, Show, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub enum SourceKind { /// GitKind() represents a git repository GitKind(String), @@ -56,7 +56,7 @@ pub enum SourceKind { RegistryKind } -#[deriving(Clone, PartialEq, Eq)] +#[deriving(Clone, PartialEq, Eq, Hash)] pub enum Location { Local(Path), Remote(Url), @@ -77,7 +77,7 @@ impl> Encodable for Location { } } -#[deriving(Encodable, Decodable, Clone, Eq)] +#[deriving(Encodable, Decodable, Clone, Eq, Hash)] pub struct SourceId { pub kind: SourceKind, pub location: Location, diff --git a/src/cargo/ops/cargo_rustc.rs b/src/cargo/ops/cargo_rustc.rs index 57cbdcfed..3d3b5660e 100644 --- a/src/cargo/ops/cargo_rustc.rs +++ b/src/cargo/ops/cargo_rustc.rs @@ -121,6 +121,7 @@ fn compile(targets: &[&Target], pkg: &Package, // TODO: Figure out how this works with targets let fingerprint_loc = cx.dest.join(format!(".{}.fingerprint", pkg.get_name())); + let (is_fresh, fingerprint) = try!(is_fresh(pkg, &fingerprint_loc, cx, targets)); @@ -244,10 +245,15 @@ fn prepare_rustc(root: &Path, target: &Target, crate_types: Vec<&str>, .env("RUST_LOG", None) // rustc is way too noisy } -fn build_base_args(into: &mut Args, target: &Target, crate_types: Vec<&str>, - cx: &Context) { +fn build_base_args(into: &mut Args, + target: &Target, + crate_types: Vec<&str>, + cx: &Context) +{ + let metadata = target.get_metadata(); + // TODO: Handle errors in converting paths into args - into.push(target.get_path().display().to_str()); + into.push(target.get_src_path().display().to_str()); into.push("--crate-name".to_str()); into.push(target.get_name().to_str()); @@ -273,6 +279,17 @@ fn build_base_args(into: &mut Args, target: &Target, crate_types: Vec<&str>, into.push("--test".to_str()); } + match metadata { + Some(m) => { + into.push("-C".to_str()); + into.push(format!("metadata={}", m.metadata)); + + into.push("-C".to_str()); + into.push(format!("extra-filename={}", m.extra_filename)); + } + None => {} + } + if target.is_lib() { into.push("--out-dir".to_str()); into.push(out.display().to_str()); diff --git a/src/cargo/util/hex.rs b/src/cargo/util/hex.rs index 7512ece21..dc1f9d611 100644 --- a/src/cargo/util/hex.rs +++ b/src/cargo/util/hex.rs @@ -1,4 +1,6 @@ use std::io::MemWriter; +use std::hash::{Hasher, Hash}; +use std::hash::sip::SipHasher; use serialize::hex::ToHex; @@ -8,3 +10,7 @@ pub fn to_hex(num: u64) -> String { writer.get_ref().to_hex() } +pub fn short_hash(hashable: &H) -> String { + let hasher = SipHasher::new_with_keys(0, 0); + to_hex(hasher.hash(hashable)) +} diff --git a/src/cargo/util/mod.rs b/src/cargo/util/mod.rs index dfeb92cb0..12f86c7d9 100644 --- a/src/cargo/util/mod.rs +++ b/src/cargo/util/mod.rs @@ -5,7 +5,7 @@ pub use self::errors::{CargoResult, CargoError, BoxError, ChainError, CliResult} pub use self::errors::{CliError, FromError, ProcessError}; pub use self::errors::{process_error, internal_error, internal, human}; pub use self::paths::realpath; -pub use self::hex::to_hex; +pub use self::hex::{to_hex, short_hash}; pub use self::pool::TaskPool; pub use self::dependency_queue::{DependencyQueue, Fresh, Dirty, Freshness}; diff --git a/src/cargo/util/toml.rs b/src/cargo/util/toml.rs index c42fc5f1c..d7713194a 100644 --- a/src/cargo/util/toml.rs +++ b/src/cargo/util/toml.rs @@ -7,6 +7,7 @@ use toml; use core::{SourceId, GitKind}; use core::manifest::{LibKind, Lib, Profile}; use core::{Summary, Manifest, Target, Dependency, PackageId}; +use core::package_id::Metadata; use core::source::Location; use util::{CargoResult, Require, human}; @@ -236,6 +237,8 @@ impl TomlManifest { human("No `package` or `project` section found.") })); + let pkgid = try!(project.to_package_id(source_id)); + let metadata = pkgid.generate_metadata(); // If we have no lib at all, use the inferred lib if available // If we have a lib with a path, we're done @@ -279,7 +282,8 @@ impl TomlManifest { // Get targets let targets = normalize(lib.as_ref().map(|l| l.as_slice()), - bins.as_ref().map(|b| b.as_slice())); + bins.as_ref().map(|b| b.as_slice()), + &metadata); if targets.is_empty() { debug!("manifest has no build targets; project={}", self.project); @@ -301,7 +305,6 @@ impl TomlManifest { try!(process_dependencies(&mut cx, true, self.dev_dependencies.as_ref())); } - let pkgid = try!(project.to_package_id(source_id)); let summary = Summary::new(&pkgid, deps.as_slice()); Ok((Manifest::new( &summary, @@ -377,7 +380,8 @@ struct TomlTarget { } fn normalize(lib: Option<&[TomlLibTarget]>, - bin: Option<&[TomlBinTarget]>) + bin: Option<&[TomlBinTarget]>, + metadata: &Metadata) -> Vec { log!(4, "normalizing toml targets; lib={}; bin={}", lib, bin); @@ -393,7 +397,7 @@ fn normalize(lib: Option<&[TomlLibTarget]>, ret } - fn lib_targets(dst: &mut Vec, libs: &[TomlLibTarget]) { + fn lib_targets(dst: &mut Vec, libs: &[TomlLibTarget], metadata: &Metadata) { let l = &libs[0]; let path = l.path.clone().unwrap_or_else(|| format!("src/{}.rs", l.name)); let crate_types = l.crate_type.clone().and_then(|kinds| { @@ -402,7 +406,8 @@ fn normalize(lib: Option<&[TomlLibTarget]>, for profile in target_profiles(l).iter() { dst.push(Target::lib_target(l.name.as_slice(), crate_types.clone(), - &Path::new(path.as_slice()), profile)); + &Path::new(path.as_slice()), profile, + metadata)); } } @@ -413,7 +418,8 @@ fn normalize(lib: Option<&[TomlLibTarget]>, for profile in target_profiles(bin).iter() { dst.push(Target::bin_target(bin.name.as_slice(), - &Path::new(path.as_slice()), profile)); + &Path::new(path.as_slice()), + profile)); } } } @@ -422,12 +428,12 @@ fn normalize(lib: Option<&[TomlLibTarget]>, match (lib, bin) { (Some(ref libs), Some(ref bins)) => { - lib_targets(&mut ret, libs.as_slice()); + lib_targets(&mut ret, libs.as_slice(), metadata); bin_targets(&mut ret, bins.as_slice(), |bin| format!("src/bin/{}.rs", bin.name)); }, (Some(ref libs), None) => { - lib_targets(&mut ret, libs.as_slice()); + lib_targets(&mut ret, libs.as_slice(), metadata); }, (None, Some(ref bins)) => { bin_targets(&mut ret, bins.as_slice(), -- 2.30.2